package main

import (
	"fmt"
	"math"
)

// 定义结构体
type Circle struct {
	radius float64
}

func main() {
	//函数调用
	//定义局部变量
	var a int = 100
	var b int = 200
	var ret int
	//调用函数并返回最大值
	ret = max(a, b)
	fmt.Printf("最大值是 ： %d\n", ret)

	aa, bb := swap("google", "runoob")
	fmt.Println(aa, bb)

	println("======================")
	fmt.Printf("交换前a的值为：%d\n", a)
	fmt.Printf("交换前b的值为：%d\n", b)
	swap2(a, b)
	fmt.Printf("交换后a的值为：%d\n", a)
	fmt.Printf("交换后b的值为：%d\n", b)

	println("======================")
	fmt.Printf("交换前a的值为：%d\n", a)
	fmt.Printf("交换前b的值为：%d\n", b)
	//调用swap3函数
	//&a 指向a指针， a变量的地址
	//&b 指向b指针， b变量的地址
	swap3(&a, &b)
	fmt.Printf("交换后a的值为：%d\n", a)
	fmt.Printf("交换后b的值为：%d\n", b)

	//Go 语言函数作为实参
	//生命函数变量
	getSquareRoot := func(x float64) float64 {
		return math.Sqrt(x)
	}
	//使用函数
	fmt.Println(getSquareRoot(9))

	println("============================")
	//函数闭包调用
	//nextNumber为一个函数，函数i为0
	nextNumber := getSequence()
	//调用nextNumber函数，i变量自增1并返回
	fmt.Println(nextNumber())
	fmt.Println(nextNumber())
	fmt.Println(nextNumber())
	println("============================")
	//创建新的函数nextNumber1，并查看结果
	nextNumber1 := getSequence()
	fmt.Println(nextNumber1())
	fmt.Println(nextNumber1())

	println("============================")
	var c1 Circle
	c1.radius = 10.00
	fmt.Println("圆的面积 = ", c1.getArea())
}

// 定义函数，返回两个数的最大值
func max(num1, num2 int) int {
	//生命局部变量
	var result int
	if num1 > num2 {
		result = num1
	} else {
		result = num2
	}
	return result
}

// go函数可以返回多个值，如
func swap(x, y string) (string, string) {
	return y, x
}

// Go 语言函数值传递值
// 定义相互交换值的函数
// 通过调用函数来交换值，程序中使用的是值传递, 所以两个值并没有实现交互
func swap2(x, y int) int {
	var temp int
	temp = x //保存x的值
	x = y    //将y的值赋给x
	y = temp //将temp的值赋给y
	return temp
}

// Go 语言函数引用传递值
// 引用传递是指在调用函数时将实际参数的地址传递到函数中，那么在函数中对参数所进行的修改，将影响到实际参数。
func swap3(x *int, y *int) {
	var temp int
	temp = *x //保存x地址上的值
	*x = *y   //将y的值赋给x
	*y = temp //将temp的值赋给y
}

// Go 语言函数闭包
func getSequence() func() int {
	i := 0
	return func() int {
		i += 1
		return i
	}
}

// 该method属于Circle类型对象中的方法
func (receiver Circle) getArea() float64 {
	//receiver.radius即为Circle类型对象中的属性
	return 3.14 * receiver.radius * receiver.radius
}
